package com.file.parser;

import com.file.bo.ResponseData;
import com.file.bo.mail.PAB;
import com.file.bo.mail.PABTran;
import com.file.constant.EfpConstants;
import com.file.constant.ErrorCode;
import com.file.parser.traprange.PDFTableExtractor;
import com.file.util.JsonUtils;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class PABPdfParser extends BasePdfParser {

	public ResponseData<String> parsePABPdfToJson(String filePath) {
		log.info("parsePABPdfToJson started, filePath:{}", filePath);
		String json = null;

		try {
			PAB pab = parsePABPdf(filePath);
			json = JsonUtils.convertObjectToJson(pab);
		} catch (Exception e) {
			log.error("[OnError]parsePABPdfToJson failed, filePath:{}", filePath, e);
			return new ResponseData<String>(json, ErrorCode.FILE_PARSE_EXCEPTION.getCode(),
					ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
		}

		log.info("parsePABPdfToJson completed, filePath:{}", filePath);
		return new ResponseData<String>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
	}

	private PAB parsePABPdf(String filePath) {
		PAB pab = parsePABHeader(filePath);
		List<PABTran> pabTrans = parsePabTrans(filePath);
		try {
			parseCounterParty(filePath, pabTrans);
		} catch (Exception e) {
			log.warn("parseConterparty failed", e);
		}

		pab.setPabTrans(pabTrans);
		log.info("pab = " + pab);
		return pab;
	}

	private PAB parsePABHeader(String filePath) {
		PAB pab = new PAB();
		String pdfHeaderText = parsePdfHeaderText(filePath);
		pdfHeaderText = pdfHeaderText.substring(0, pdfHeaderText.indexOf("序号"));

		String name = pdfHeaderText.substring(pdfHeaderText.indexOf("户名:") + 3, pdfHeaderText.indexOf("账号:")).trim();
		String accountNo = pdfHeaderText.substring(pdfHeaderText.indexOf("账号:") + 3, pdfHeaderText.indexOf("卡号:"))
				.trim();
		String cardNo = pdfHeaderText.substring(pdfHeaderText.indexOf("卡号:") + 3, pdfHeaderText.indexOf("币种:")).trim();
		String currency = pdfHeaderText.substring(pdfHeaderText.indexOf("币种:") + 3, pdfHeaderText.indexOf("存款类型:"))
				.trim();
		String depositType = pdfHeaderText.substring(pdfHeaderText.indexOf("存款类型:") + 5, pdfHeaderText.indexOf("交易日期:"))
				.trim();
		String transactionDate = pdfHeaderText
				.substring(pdfHeaderText.indexOf("交易日期:") + 5, pdfHeaderText.indexOf("开户行:")).trim();
		String accountBank = pdfHeaderText.substring(pdfHeaderText.indexOf("开户行:") + 4, pdfHeaderText.indexOf("受理行:"))
				.trim();
		String receivingBank = pdfHeaderText
				.substring(pdfHeaderText.indexOf("受理行:") + 4, pdfHeaderText.indexOf("打印日期:")).trim();
		String printDate = pdfHeaderText.substring(pdfHeaderText.indexOf("打印日期:") + 5, pdfHeaderText.indexOf("流水范围:"))
				.trim();
		String transactionRange = pdfHeaderText.substring(pdfHeaderText.indexOf("流水范围:") + 5).trim();

		pab.setName(name);
		pab.setAccountNo(accountNo);
		pab.setCardNo(cardNo);
		pab.setCurrency(currency);
		pab.setDepositType(depositType);
		pab.setTransactionDate(transactionDate);
		pab.setAccountBank(accountBank);
		pab.setReceivingBank(receivingBank);
		pab.setPrintDate(printDate);
		pab.setTransactionRange(transactionRange);

		return pab;
	}

	private List<PABTran> parsePabTrans(String filePath) {
		List<PABTran> pabTrans = new ArrayList<>();

		String transText = parseTransToText(filePath);
		if (Strings.isNullOrEmpty(transText)) {
			return pabTrans;
		}

		List<List<String>> tranFieldsList = parseTransTextToTranFieldsList(transText);

		for (List<String> strings : tranFieldsList) {
			if (StringUtils.isNoneBlank(strings.get(1))) {
				// log.info(strings.toString());
				PABTran pabTran = new PABTran();
				pabTran.setId(strings.get(1));
				pabTran.setTransactionTime(strings.get(2));
				pabTran.setTransactionAmount(strings.get(3));
				pabTran.setBalance(strings.get(4));
				pabTran.setTransactionType(strings.get(5));
				pabTrans.add(pabTran);
			}
		}
		return pabTrans;
	}

	private String parseTransToText(String filePath) {
		PDFTableExtractor extractor = (new PDFTableExtractor()).setSource(filePath);
		int pdfPageNumber = getPdfPageNumber(filePath);

		for (int k = 0; k < pdfPageNumber; k++) {
			int[] skipLinesIndexes = new int[EfpConstants.PAB_PDF_HEADER_LINE_NUMBER
					+ EfpConstants.PAB_PDF_FOOTER_LINE_NUMBER];
			for (int i = 0; i < EfpConstants.PAB_PDF_HEADER_LINE_NUMBER; i++) {
				skipLinesIndexes[i] = i;
			}
			for (int j = 0; j < EfpConstants.PAB_PDF_FOOTER_LINE_NUMBER; j++) {
				skipLinesIndexes[EfpConstants.PAB_PDF_HEADER_LINE_NUMBER + j] = -(j + 1);
			}
			extractor.exceptLine(k, skipLinesIndexes);
		}
		return extractPdfToText(extractor);
	}

	private void parseCounterParty(String filePath, List<PABTran> pabTrans) {
		String pdfText = getPdfTextByStripper(filePath);
		pdfText = pdfText.replace(System.getProperty("line.separator", "\n"), " ");

		// 此处一行的格式1 20210916 -0.01 0.66 转账 招商银行股份有限公司-胡朝新 -6214861021778877
		Pattern pattern1 = Pattern.compile("\\d{1,5}\\s\\d{8}\\s.{1}\\d{1,9}.\\d{2}\\s\\d{1,9}.\\d{2}\\s");
		Matcher matcher1 = pattern1.matcher(pdfText);

		// 每行交易记录的第一个字所在的index
		int tranIndex = 0;
		Map<Integer, Integer> tranTextStartIndexMap = new HashMap<>();

		while (matcher1.find()) {
//			log.info(
//			"Match \"" + matcher1.group() + "\" at positions " + matcher1.start() + "-" + (matcher1.end() - 1));
			tranTextStartIndexMap.put(tranIndex, matcher1.start());
			tranIndex++;
		}

		// 找出每行交易记录的文本
		List<String> tranTextList = new ArrayList<>();
		for (int i = 1; i < tranTextStartIndexMap.size(); i++) {
			String tranText = pdfText.substring(tranTextStartIndexMap.get(i - 1), tranTextStartIndexMap.get(i));
			if (tranText.contains("平安银行个人账户交易明细清单")) {
				tranText = tranText.substring(0, tranText.indexOf("平安银行个人账户交易明细清单")).trim();
			}
			tranTextList.add(tranText.trim());
		}

		String lastTranText = pdfText.substring(tranTextStartIndexMap.get(tranTextStartIndexMap.size() - 1));
		lastTranText = lastTranText.substring(0, lastTranText.indexOf("平安银行个人账户交易明细清单")).trim();
		tranTextList.add(lastTranText);

		// 找出每行交易里的对手信息的值
		// 此处一行除去对手户名的格式 此处一行的格式1 20210916 -0.01 0.66 转账 招商银行股份有限公司-胡朝新
		// -6214861021778877
		Pattern pattern2 = Pattern.compile("\\d{1,5}\\s\\d{8}\\s.{1}\\d{1,9}.\\d{2}\\s\\d{1,9}.\\d{2}\\s\\S{1,15}\\s");
		for (int i = 0; i < pabTrans.size(); i++) {
			Matcher matcher2 = pattern2.matcher(tranTextList.get(i));
			while (matcher2.find()) {
//				log.info(
//				"Match \"" + matcher2.group() + "\" at positions " + matcher2.start() + "-" + (matcher2.end() - 1));
				String counterParty = tranTextList.get(i).substring(matcher2.end()).trim();
				pabTrans.get(i).setCounterParty(counterParty.replace(" ", ""));
			}
		}
	}

	public static void main(String[] args) {
		PABPdfParser pabPdfParser = new PABPdfParser();
		PAB pab = pabPdfParser.parsePABPdf("E:\\data\\files\\PAB\\平安银行交易明细.pdf");
		String json = JsonUtils.convertObjectToJson(pab);
		log.info(json);
	}

}
